package demo7.CallCenter;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.checkerframework.checker.units.qual.A;

import javax.annotation.concurrent.ThreadSafe;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@EqualsAndHashCode(callSuper=false)
@Data
public class CallCenter {
    public List<Operator> operators=new ArrayList<>();
    public List<Director> directors=new ArrayList<>();
    public Manager manager=new Manager("hcj",false);
    public int freeOperators=operators.size();
    public int freeDirectors=directors.size();
    Random random = new Random();
    public CallCenter(){
        initStaffInfo();;
    }

    public void initStaffInfo(){
        operators.add(new Operator("h",false));
        operators.add(new Operator("c",false));
        operators.add(new Operator("j",false));
        directors.add(new Director("x", false));
        directors.add(new Director("y", false));
    }


    public Operator getFreeOperatorImmediately(){
        List<Operator> collect = operators.stream().filter(operator -> {
            return !operator.isBuzy();
        }).collect(Collectors.toList());
        if(collect.size()==0)return null;
        int size = collect.size();
        // 0,1,2
        int i = random.nextInt(size );
        return collect.get(i);
    }
    public Director getFreeDirectorImmediately(){
        List<Director> collect = directors.stream().filter(director -> {
            return !director.isBuzy();
        }).collect(Collectors.toList());
        int size = collect.size();
        int i = random.nextInt(size );
        return collect.get(i);
    }
    public Manager getFreeManagerImmediately(){
        return manager.isBuzy?null:manager;
    }

    public enum Human {
        OPERATOR, DIRECTOR, MANAGER;
    }

    // 3 op ,2 director ,1 manager,
    public abstract class People {
        public abstract void wiring(Event event) throws InterruptedException;
        public abstract boolean handle(Event event) ;
    }
    @Data
    @EqualsAndHashCode(callSuper=false)
    @AllArgsConstructor
    @NoArgsConstructor
    public class Operator extends People {

        private String name;
        public boolean isBuzy=false;

        @Override
        public void wiring(Event event) throws InterruptedException {
            isBuzy=true;
            Thread.sleep(10000);
            System.out.println("operator : " + name + " --- wiring, with the event type: "+ event.getEventType().name()+" no is"+event.getNo());
        }
        @Override
        public boolean handle(Event event)  {
            try {
               wiring(event);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            isBuzy=false;
            if(event.getEventType()==EventType.EASY ){
                return true;
            }
            System.out.println("operator :"+name+" don't deal with the event type: "+event.getEventType().name()+" no is"+event.getNo());
            return false;
        }

    }
    @Data
    @EqualsAndHashCode(callSuper=false)
    @AllArgsConstructor
    @NoArgsConstructor
    public class Director extends People {
        private String name;
        public boolean isBuzy=false;
        @Override
        public void  wiring(Event event) throws InterruptedException {
            isBuzy=true;
            Thread.sleep(5000);
            System.out.println("director : " + name + " --- wiring, with the event type: "+ event.getEventType().name()+" no is"+event.getNo());
        }
        @Override
        public boolean handle(Event event) {
            try {
                 wiring(event);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            isBuzy=false;
            if(event.getEventType()==EventType.EASY || event.getEventType()==EventType.MODERATION){
                return true;
            }
            System.out.println("director :"+name+" don't deal with the event type: "+event.getEventType().name()+" no is"+event.getNo());
            return false;
        }
    }
    @Data
    @EqualsAndHashCode(callSuper=false)
    @AllArgsConstructor
    @NoArgsConstructor
    public class Manager extends People {
        private String name;
        private boolean isBuzy;

        @Override
        public void wiring(Event event) {
            System.out.println("manager : " + name + " --- wiring, with the event type: "+ event.getEventType().name()+" no is"+event.getNo());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        @Override
        public boolean handle(Event event) {
            isBuzy=false;
            wiring(event);
            isBuzy=true;
            System.out.println("manager :"+manager+" can deal with the event type: "+event.getEventType().name()+" no is"+event.getNo());
            return true;
        }
    }


}
